<?php

namespace App\Modules\Apicrzs\Services\Notify;

use App\Exceptions\Exception;
use App\Library\Wechat\PayWeChatApi;
use App\Library\Pay\AliPayService;
use App\Modules\Admin\Entities\Equipment\EquipmentParamsFreeModel;
use App\Modules\Admin\Entities\Log\OrderJundaLogModel;
use App\Modules\Admin\Entities\Member\UserCardModel;
use App\Modules\Admin\Entities\Pay\OrderRefundModel;
use App\Modules\Admin\Entities\Water\WaterDeviceModel;
use App\Modules\Admin\Services\BaseService;
use App\Modules\Admin\Entities\Water\WaterOrderModel;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;


class JunDaNotifyServices extends BaseService
{
    protected $open_refund = true;

    /**
     *  梳理骏达订单 回调 api
     * @param $params
     * @return true
     * @throws Exception
     */
    public function callback($params)
    {
        $params = json_decode($params,true);
        xdebug($params,'骏达请求接口-回调-api','','junda/callback');
        OrderJundaLogModel::getInstance()->paramsLog($params);

        $desc = json_encode($params);
        $insert = [
            'mid' => $params['mid'],
            'conchannel' => $params['conchannel'],
            'conwater' => $params['conwater'] / 1000,
            'iseff' => $params['iseff'] ?? 0,
            'created_time' => date('Y-d-m H:i:s'),
            'updated_time' => date('Y-d-m H:i:s'),
            'desc' => $desc
        ];
        if (isset($params['conMoney'])) {
            $insert['buyMoney'] = $params['buyMoney'];
            $insert['conMoney'] = $params['conMoney'];
            $insert['equipmentId'] = $params['equipmentId'];
            $insert['orderNo'] = $params['orderNo'];
            $insert['cardNo'] = $params['cardNo'];
            $orderNo = $params['orderNo'];
        } else {
            $orderNo = $params['orderno'];
            $insert['buymoney'] = $params['buymoney'];
            $insert['conmoney'] = $params['conmoney'];
            $insert['equipmentid'] = $params['equipmentid'];
            $insert['orderno'] = $params['orderno'];
            $insert['cardno'] = $params['cardno'];
        }
        if (!$orderNo) {
            // 刷卡
            $res = $this->swipeOrder($insert);
        } else {
            // 扫码
            $res = $this->onlineCard($insert);
        }
        return $res;
    }


    /**
     *  线上扫码 订单 处理
     * @param $params
     * @return true
     * @throws Exception
     */
    protected function onlineCard($params)
    {
        $cardNo = $params['cardno'] ?? "";
        $buyMoney = ($params['buymoney'] ?? 0) / 100; //消费金额
        $conMoney = ($params['conmoney'] ?? 0) / 100; //消费金额
        $orderNo = $params['orderno'] ?? "";
        $equipmentId = $params['equipmentid'];
        $conwater = $params['conwater'];

        $order_info = WaterOrderModel::getInstance()->getWaterOrderByOrderSn($orderNo);
        $card_no = $order_info['card_no'];
        $value_after =$value_before = 0;
        if($card_no){
            $card_info = UserCardModel::getInstance()->getUserByCardNo($card_no);
            $value_before = $card_info['remaining_value'] ?? 0;//消费前余额
            if ($value_before) {
                $value_after = number_format($value_before - $conMoney, 2);//消费后余额
            }
            UserCardModel::getInstance()->remainingValueDecrement($card_no, $conMoney);
        }
        $pay_type = $order_info['pay_type'];
        $refund_price = number_format($buyMoney - $conMoney, 2);

        DB::beginTransaction();
        try {
            WaterOrderModel::getInstance()->updateWaterOrderByOrderSn($orderNo, [
                'value_before' => $value_before,
                'value_after' => $value_after,
                'total_price' => $buyMoney,
                'buy_money' => $buyMoney,
                'amount' => $conMoney,
                'con_water' => $conwater,
                'is_water' => 1,
            ]);
            if ($params['iseff'] == 0) {
                UserCardModel::getInstance()->remainingValueDecrement($cardNo, $conMoney);
            }

            if ($this->open_refund) {
                $res_refund =   $this->WeChatAsAlipayAutomaticRefundConsume($params);
            }

            /*if ($pay_type == 'weixin' && $order_info['status'] == 1) {
                // 微信 退款
                if ($this->open_refund) {
                    $this->WeChatAutomaticRefundConsume($params);
                }
            } elseif ($pay_type == 'alipay' && $order_info['status'] == 1) {
                // 支付宝 退款
                if ($this->open_refund) {
                    $this->AlipayAutomaticRefundConsume($params);
                }
            }*/
            DB::commit();
            return true;
        } catch (Exception $e) {
            DB::rollBack();
            throw new Exception($e->getMessage());
        }

    }

    /**
     *  刷卡 订单处理
     * @param $params
     * @return true
     * @throws Exception
     */
    protected function swipeOrder($params)
    {
        $cardNo = $params['cardNo'] ?? "";
        $buyMoney = ($params['buyMoney'] ?? 0) / 100; //消费金额
        $conMoney = ($params['conMoney'] ?? 0) / 100; //消费金额
        $orderNo = WaterOrderModel::getInstance()->findAvailableNo();
        $equipmentId = $params['equipmentId'];

        $card_info = UserCardModel::getInstance()->getUserByCardNo($cardNo);
        $pay_type ='default';
        if ($card_info){
            $pay_type ='online_card';
        }
        $value_before = $card_info['remaining_value'] ?? 0;//消费前余额
        $value_after = 0;
        if ($value_before) {
            $value_after = bcsub($value_before,$conMoney,2);//消费后余额
        }

        $balance = $params['balance'] ?? 0;// 剩余金额
        $conChannel = $params['conChannel'] ?? 1;// 消费通道（int类型）
        $conWater = $params['conwater'] ?? "";// 打水量（decimal类型，单位毫升）
        $iseff = $params['iseff'] ?? 0;// 是否时效套餐消费（int类型，1代表时效套餐消费）
        // $free_info = $this->getEquipmentFreeById($equipmentId, $conChannel);

        $free_info = Cache::get('water:device:job_cache:eq_all:'.$equipmentId);

        xdebug($free_info,'处理结果-回调-api','','junda/IC');
        $free_info_type = isset($free_info['type'])?$free_info['type']==3:false;
        if ($free_info_type){
            $conChannel = 3;
        }
        xdebug($conChannel,'处理结果-$conChannel-api','','junda/callback');

        $remark=[
            1=>'直饮水',
            2=>'矿化水',
            3=>'富氢水',
        ];

        if ($free_info) {
            $update_order['water_id'] = $free_info['water_id'] ?? 0;
            $update_order['apparatus_type'] = $conChannel;
            $update_order['order_sn'] = $free_info['water_id'] .'-' . $orderNo;
            $update_order['user_card_id'] = $card_info['user_card_id'] ?? 0;
            $update_order['type'] = 'consume';
            $update_order['card_no'] = $cardNo;
            $update_order['user_id'] = $card_info['user_id'] ?? 0;
            $update_order['value_before'] = $value_before;
            $update_order['value_after'] = $value_after;
            $update_order['total_price'] = $conMoney;
            $update_order['amount'] = $conMoney;
            $update_order['buy_money'] = $buyMoney;
            $update_order['con_water'] = $conWater;
            $update_order['payment_method'] = "default";
            $update_order['usage_type'] = "default";
            $update_order['pay_type'] = $pay_type;
            $update_order['pay_time'] = time();
            $update_order['status'] = 1;
            $update_order['remark'] = $remark[$conChannel] ?? 0;
            $update_order['operator_name'] = '刷卡';
            $update_order['iseff'] = $iseff;
            $update_order['is_water'] = 1;
            DB::beginTransaction();
            try {
                UserCardModel::getInstance()->updateUserByCardNo($cardNo, ['remaining_value' => $value_after, 'water_id' => $free_info['water_id']]);
                WaterOrderModel::getInstance()->create($update_order);
                DB::commit();
                return true;
            } catch (Exception $e) {
                DB::rollBack();
                throw new Exception($e->getMessage());
            }
        }
    }

    public function getEquipmentFreeById($equipmentId, $type)
    {
        $free_info = [];
        $equipment_info = WaterDeviceModel::getInstance()->where(['equipment_id' => $equipmentId])->Orwhere(['equipment_id_rich' => $equipmentId])->first();
        if ($equipment_info) {
            if ($equipment_info['equipment_id'] === $equipmentId) {
                $free_info = EquipmentParamsFreeModel::getInstance()->getWaterDeviceIdByType($equipment_info['water_id'], $type);
            } elseif ($equipment_info['equipment_id_rich'] === $equipmentId) {
                $free_info = EquipmentParamsFreeModel::getInstance()->getWaterDeviceIdByType($equipment_info['water_id'], 3);
            }
        }
        return $free_info;
    }

    protected function WeChatAsAlipayAutomaticRefundConsume($params)
    {
        $order_info = WaterOrderModel::getInstance()->getWaterOrderByOrderSn($params['orderno']);
        $order_id = $order_info['order_id'];
        $order_sn = $order_info['order_sn'];
        $buymoney = $params['buymoney'];
        $conmoney = $params['conmoney'];
        $refund_price = ($buymoney - $conmoney) / 100;
        $pay_type = $order_info['pay_type'];

        DB::beginTransaction();
        try {
            if($refund_price) {
                if ($pay_type=='weixin'){
                    $refund_res = PayWeChatApi::pay_refunds([
                        'order_sn' => $order_sn,
                        'total' => $buymoney/100,
                        'refund_amount' => $refund_price,
                        'out_refund_no' => time(),
                    ]);
                    if (isset($refund_res['code'])) {
                        DB::rollBack();
                        $this->error = $refund_res['message'];
                        return false;
                    }
                    $payer_refund = ($refund_res['amount']['payer_refund'] / 100);
                }elseif ($pay_type=='alipay'){
                    //exit(json_encode($refund_price));
                    $refund_res =  AliPayService::instance()->refund($order_sn,$refund_price,$order_sn.'001');
                    // if ($refund_res->code!=10000){
                    //     $this->error=$refund_res['msg'];
                    //     return false;
                    // }

                    $payer_refund = $refund_res->refundFee;
                }

                $refund_status = 1;
                $refund_info = OrderRefundModel::getInstance()->create([
                    'user_id' => $order_info['user_id'],
                    'order_id' => $order_id,
                    'order_sn' => $order_sn,
                    'type' => $pay_type,
                    'refund_price' => $refund_price,
                    'refunded_time' => date('Y-m-d H:i:s'),
                    'desc' => json_encode($refund_res),
                    'operator_name' => '',
                ]);
                $refund_prices = $order_info['refund_price'] + $payer_refund;

                WaterOrderModel::getInstance()->updateWaterOrderByOrderId($order_id, [
                    'refund_price' => $refund_prices,
                    'refund_id' => $refund_info['refund_id'],
                    'refund_type' => $pay_type,
                    'refund_time' => time(),
                    'refund_status' => $refund_status,
                    'refund_desc' => json_encode($refund_info),
                ]);
            }
            DB::commit();
            return true;
        } catch (Exception $e) {
            DB::rollBack();
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 微信  自动退款
     * @param $params
     * @return false|void
     */
    protected function WeChatAutomaticRefundConsume($params)
    {
        $order_info = WaterOrderModel::getInstance()->getWaterOrderByOrderSn($params['orderno']);
        $order_id = $order_info['order_id'];
        $order_sn = $order_info['order_sn'];
//        $refund_price = $params['refund_price'];

        $buymoney = $params['buymoney'];
        $conmoney = $params['conmoney'];
        $refund_price = ($buymoney - $conmoney) / 100;
        $pay_type = $order_info['pay_type'];
        // 微信
        DB::beginTransaction();
        try {
            $refund_param = [
                'order_sn' => $order_sn,
                'total' => $buymoney/100,
                'refund_amount' =>$refund_price,
                'out_refund_no' => time(),
            ];
            if($refund_price){
                $refund_res = PayWeChatApi::pay_refunds($refund_param);
                //exit(json_encode($refund_price));
                if (isset($refund_res['code'])) {
                    DB::rollBack();
                    $this->error = $refund_res['message'];
                    return false;
                }
                $refund_status = 1;
                $refund_info = OrderRefundModel::getInstance()->create([
                    'user_id' => $order_info['user_id'],
                    'order_id' => $order_id,
                    'order_sn' => $order_sn,
                    'type' => $pay_type,
                    'refund_price' => $refund_price,
                    'refunded_time' => date('Y-m-d H:i:s'),
                    'desc' => json_encode($refund_res),
                    'operator_name' => '',
                ]);
                $refund_prices = $order_info['refund_price'] + ($refund_res['amount']['payer_refund'] / 100);

                WaterOrderModel::getInstance()->updateWaterOrderByOrderId($order_id, [
                    'refund_price' => $refund_prices,
                    'refund_id' => $refund_info['refund_id'],
                    'refund_type' => $pay_type,
                    'refund_time' => time(),
                    'refund_status' => $refund_status,
                    'refund_desc' => json_encode($refund_info),
                ]);
            }
            DB::commit();
            return true;
        } catch (Exception $e) {
            DB::rollBack();
            throw new Exception($e->getMessage());
        }
    }
    public function testWxRefund($params)
    {
        return $this->WeChatAutomaticRefundConsume($params);
    }
    public function AlipayAutomaticRefundConsume($params)
    {
        DB::beginTransaction();
        try {
            DB::commit();
            return true;
        } catch (Exception $e) {
            DB::rollBack();
            throw new Exception($e->getMessage());
        }
    }
}
